﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing.Drawing2D;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace Xin478.CSWork.Client
{
    public partial class MyTreeView : TreeView
    {
        Color nodeBackgroundColorBegin = Color.FromArgb(233, 239, 249);
        Color nodeBackgroundColorEnd = Color.FromArgb(214, 224, 241);
        Color nodeBorderColor = Color.FromArgb(205, 228, 255);

        public MyTreeView()
        {
            this.ItemHeight = 20;
            this.NodeTextIndent = 20;
            this.ImageIndent = 5;
            this.DrawMode = TreeViewDrawMode.OwnerDrawAll;
            base.SetStyle(ControlStyles.OptimizedDoubleBuffer,true);
        }

        public Image NodePlusImage { get; set; }
        public Image NodeMinusImage {get;set;}

        [DefaultValueAttribute(20)]
        public int NodeTextIndent { get; set; }
        [DefaultValueAttribute(5)]
        public int ImageIndent { get; set; }

        protected override void OnDrawNode(DrawTreeNodeEventArgs e)
        {
            if (e.Node.Level != 0 && e.Bounds.X == 0 && e.Bounds.Y == 0) return;
            Rectangle rect = e.Bounds;
            Graphics g = e.Graphics;
            
            if (e.Node.IsSelected)
            {
                LinearGradientMode mode = LinearGradientMode.Vertical;

                using (LinearGradientBrush brush = new LinearGradientBrush(rect, nodeBackgroundColorBegin, nodeBackgroundColorEnd, mode))
                {
                    g.FillRectangle(brush, rect.X + 1, rect.Y + 1, rect.Width - 3, rect.Height - 3);
                }
                //绘制渐变背景
                using (Pen p = new Pen(nodeBorderColor, 1))
                {
                    DrawRoundRect(g, p, rect.X, rect.Y, rect.Width - 1, rect.Height - 1, 3);
                    //p.Color = Color.FromArgb(231, 237, 249);
                    p.Color = Color.FromArgb(244, 247, 253);
                    DrawRoundRect(g, p, rect.X + 1, rect.Y + 1, rect.Width - 3, rect.Height - 3, 3);
                }
            }
            else if (this.HotTracking)
            {
                if (e.State == TreeNodeStates.Hot)
                {
                    using (Pen p = new Pen(nodeBorderColor, 1))
                    {
                        DrawRoundRect(g, p, rect.X, rect.Y, rect.Width - 1, rect.Height - 1, 3);
                    }
                }
                else
                {
                    using (Brush tmpb = new SolidBrush(this.BackColor))
                    {
                        g.FillRectangle(tmpb, rect);
                    }
                }
            }

            if (this.ShowPlusMinus && e.Node.Nodes.Count > 0 && NodePlusImage != null && NodeMinusImage!=null)
            {
                g.DrawImage((e.Node.IsExpanded ? this.NodePlusImage : this.NodeMinusImage), e.Bounds.Location.X + this.ImageIndent + this.Indent * e.Node.Level, e.Bounds.Location.Y + 5);
            }
            
            //绘制文字
            
            Font f;
            if (e.Node.IsSelected)
            {
                f = new Font(this.Font, FontStyle.Bold);
            }
            else
            {
                f = this.Font;
            }

            using (Brush b = new SolidBrush(e.Node.ForeColor.IsEmpty ? this.ForeColor : e.Node.ForeColor))
            {
                g.DrawString(e.Node.Text, f, b, (e.Bounds.Location.X + this.NodeTextIndent + this.Indent * e.Node.Level), (e.Bounds.Location.Y + 4));

                //System.Diagnostics.Debug.WriteLine(e.Node.Text +e.State.ToString()+ " " + e.Bounds.Location.X + "," + e.Bounds.Location.Y);
            }

            base.OnDrawNode(e);
        }

        void DrawRoundRect(Graphics g, Pen p, float X, float Y, float width, float height, float radius)
        {
            using (GraphicsPath gp = new GraphicsPath())
            {
                gp.AddLine(X + radius, Y, X + width - (radius * 2), Y);
                gp.AddArc(X + width - (radius * 2), Y, radius * 2, radius * 2, 270, 90);
                gp.AddLine(X + width, Y + radius, X + width, Y + height - (radius * 2));
                gp.AddArc(X + width - (radius * 2), Y + height - (radius * 2), radius * 2, radius * 2, 0, 90);
                gp.AddLine(X + width - (radius * 2), Y + height, X + radius, Y + height);
                gp.AddArc(X, Y + height - (radius * 2), radius * 2, radius * 2, 90, 90);
                gp.AddLine(X, Y + height - (radius * 2), X, Y + radius);
                gp.AddArc(X, Y, radius * 2, radius * 2, 180, 90);
                gp.CloseFigure();
                g.DrawPath(p, gp);
            }
        }  

    }
}
